using System;
using System.Collections;
using System.Collections.Generic;
using Gj.Galaxy.Logic;
using MessagePack;
using SimpleJSON;
using UnityEngine;

namespace Gj.MapData
{
    public class MapBuilder
    {
        protected MapDefine _mapDefine;
        protected MapPath _mapPath;
        protected List<MapPosition> _mapPositions;


        public static MapBuilder Get()
        {
            var builder = new MapBuilder();
            builder._mapPath = new MapPath();

            builder._mapDefine = new MapDefine();
            builder._mapPositions = new List<MapPosition>();

            return builder;
        }

        public MapBuilder Mode(MapMode mode)
        {
            _mapPath.Mode = mode;
            return this;
        }

        public MapBuilder Size(int width, int height)
        {
            _mapPath.Size = new Vector2Int(width, height);
            return this;
        }

        public MapBuilder Block(int width, int height)
        {
            _mapPath.Block = new Vector2Int(width, height);
            return this;
        }

        public MapBuilder Center(Vector2Int center)
        {
            _mapPath.Center = center;
            return this;
        }

        public MapBuilder SetDataNode(List<DataNode> a)
        {
            _mapPath.DataNodes = a.ToArray();
            return this;
        }

        public MapBuilder SetBoundary(List<Vector2Int> boundary)
        {
            _mapPath.Boundary = boundary;
            return this;
        }

        public MapBuilder AddDefineNode(DefineNodeData data)
        {
            _mapDefine.Nodes ??= new List<DefineNodeData>();
            _mapDefine.Nodes.Add(data);
            return this;
        }

        public MapBuilder SelectPosition(string name, Vector2Int position)
        {
            _mapPositions.Add(new MapPosition { Id = position.x + "," + position.y, Name = name, Position = position });
            return this;
        }

        public byte[] PathData()
        {
            return MessagePackSerializer.Serialize(_mapPath.Object());
        }

        public JSONObject InitData()
        {
            return _mapDefine.Object();
        }

        public byte[] SelectPosition()
        {
            return MessagePackSerializer.Serialize(MapPosition.Array(_mapPositions.ToArray()));
        }

        public static IEnumerator CreateMap(string userId, byte[] pathData, JSONObject defineData, Action<int> result)
        {
            var data = new JSONObject();
            data["userId"] = userId;
            data["name"] = "test";
            data["people"] = 100;
            data["aiNumber"] = 10;
            data["path"] = Convert.ToBase64String(pathData);
            data["define"] = defineData.ToString();
            return Manager.Post($"http://{Manager.Domain}{Manager.settings.mapApi}/create", data,
                r => { result(r.AsInt); });
        }

        public static IEnumerator UpdateMap(string userId, int mapId, byte[] pathData, JSONObject defineData,
            byte[] selectPosition, Action<int> result)
        {
            var data = new JSONObject();
            data["userId"] = userId;
            data["mapId"] = mapId;
            data["people"] = 100;
            data["aiNumber"] = 10;
            data["path"] = Convert.ToBase64String(pathData);
            data["define"] = defineData.ToString();
            data["selectPosition"] = Convert.ToBase64String(selectPosition);
            return Manager.Post($"http://{Manager.Domain}{Manager.settings.mapApi}/update", data,
                r => { result(r.AsInt); });
        }
        public static IEnumerator PointMap(string mapNo, string type, int t, Vector2Int[] positions, Action<int> result)
        {
            var data = new JSONObject();
            var list = new JSONArray();
            for (var i = 0; i < positions.Length; i++)
            {
                var position = positions[i];
                var node = new JSONObject();
                node["position"] = position.x + "," + position.y;
                node["key"] = t;
                list.Add(node);
            }

            data["type"] = "roadblock";
            data["minX"] = 0;
            data["minY"] = 0;
            data["maxX"] = 0;
            data["maxY"] = 0;
            data["list"] = list;
            return Manager.Post($"http://{Manager.Domain}{Manager.settings.mapApi}/points/{mapNo}", data, r =>
            {
                result(r.AsInt);
            });
        }
        public static IEnumerator PathMap(string mapNo, byte[] start, byte[] end, Action<Vector2Int[]> result)
        {
            var data = new JSONObject();
            data["start"] = Convert.ToBase64String(start);
            data["end"] = Convert.ToBase64String(end);
            return Manager.Get($"http://{Manager.Domain}{Manager.settings.mapApi}/path/{mapNo}", data, r =>
            {
                var tt = r.ToString();
                var ps = Convert.FromBase64String(tt);
                var ds = MessagePackSerializer.Deserialize<object[]>(ps);
                var positions = new Vector2Int[ds.Length];
                for (var i = 0; i < positions.Length; i++) positions[i] = SerializeInt.Byte2Vector((byte[])ds[i]);

                result(positions);
            });
        }
    }
}